package concurrent;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;

/**
 * TODO 简单说明
 *
 * @author yangyang
 * @date 2017/7/14 10:03
 * @email kekecany@163.com
 */
class LiftOffRunner implements Runnable {

    private BlockingQueue<LiftOff> blockingQueue;

    public LiftOffRunner(BlockingQueue<LiftOff> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    public void add(LiftOff liftOff) {
        try {
            blockingQueue.put(liftOff);
        } catch (InterruptedException e) {
            System.out.println("put interruption");
        }
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                LiftOff liftOff = blockingQueue.take();
                liftOff.run();
            }
        } catch (InterruptedException e) {
            System.out.println("run interruption");
        }
        System.out.println("exit run");
    }
}

public class TestBlockingQueues {
    private static void getKey() {
        try {
            new BufferedReader(new InputStreamReader(System.in)).readLine();
        } catch (IOException e) {
            System.out.println("io exception");
        }
    }

    private static void getKey(String msg) {
        System.out.println(msg);
        getKey();
    }

    static void test(String msg, BlockingQueue<LiftOff> blockingQueue) {
        System.out.println(msg);
        LiftOffRunner liftOffRunner = new LiftOffRunner(blockingQueue);
        Thread t = new Thread(liftOffRunner);
        t.start();
        for (int i = 0; i < 5; i++) {
            liftOffRunner.add(new LiftOff(5));
        }
        getKey("press Enter :" + msg);
        t.interrupt();
        System.out.println("finished test " + msg);
    }

    public static void main(String[] args) {
        test("LinkedBlockingQueue", new LinkedBlockingQueue<>());
        test("ArrayBlockingQueue", new ArrayBlockingQueue<>(3));
        test("SynchronousQueue", new SynchronousQueue<>());
    }
}
